using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Conusic;
using Imager.LastFmAutocomplete;

namespace Imager
{
    public sealed partial class TextBoxLastfmAutocomplete : TextBox
    {
        private readonly Thread lastFmAutocompleteFormWorker;
        private LastFmAutocompleteForm lastFmAutocompleteForm;
        private bool silince;

        public TextBoxLastfmAutocomplete()
        {
            lastFmAutocompleteFormWorker = new Thread(delegate()
                                                          {
                                                              lastFmAutocompleteForm = new LastFmAutocompleteForm();
                                                              this.lastFmAutocompleteForm.OnSelect += OnSelectHint;
                                                              Application.Run(lastFmAutocompleteForm);
                                                          });
            lastFmAutocompleteFormWorker.IsBackground = true;
            lastFmAutocompleteFormWorker.Start();


            InitializeComponent();
            this.TextChanged += OnMoveParent;

            //
            this.ParentChanged += OnChanged;
        }

        private void OnSelectHint(object sender, EventArgs e)
        {
            if (this.InvokeRequired)
            {
                BeginInvoke(new MethodInvoker(() => OnSelectHint(sender, e)));
                return;
            }


            var autocompleteItem = sender as AutocompleteItem;
            if (autocompleteItem == null)
                return;

            SilenceUpdateText(autocompleteItem.Hint.ToString());

            switch (autocompleteItem.Hint.HintCategory)
            {
                case LastFm.HintType.Artist:
                    break;
                case LastFm.HintType.Album:
                    break;
                case LastFm.HintType.Tag:
                    break;
                case LastFm.HintType.Track:
                    var song = (AudioRecord) autocompleteItem.Hint;
                    var playlist = new Playlist(song);
                    string plfile = playlist.SaveM3U();
                    System.Diagnostics.Process.Start(plfile);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            HideAutocompleteForm();
        }


        #region Move events

        private void OnChanged(object sender, EventArgs e)
        {
            this.Parent.Move += OnMoveParent;
            Parent.Click += TextBoxLastfmAutocompleteLeave;
        }

        private void OnMoveParent(object a, EventArgs b)
        {
            if (lastFmAutocompleteForm != null && lastFmAutocompleteForm.Created)
            {
                var x = this.PointToScreen(new Point(0, this.Height));

                lastFmAutocompleteForm.Invoke(new MethodInvoker(() => lastFmAutocompleteForm.Location = x));
            }
        }

        #endregion

        private void InitializeComponent()
        {
            this.SuspendLayout();
            // 
            // TextBoxLastfmAutocomplete
            // 
            this.Font = new System.Drawing.Font("Microsoft Sans Serif", 14F);
            this.TextChanged += new System.EventHandler(this.TextBoxLastfmAutocompleteTextChanged);
            this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.TextBoxLastfmAutocompleteKeyPress);
            this.Leave += new System.EventHandler(this.TextBoxLastfmAutocompleteLeave);
            this.ResumeLayout(false);

        }

        private void TextBoxLastfmAutocompleteLeave(object sender, System.EventArgs e)
        {
            HideAutocompleteForm();
        }

        private void TextBoxLastfmAutocompleteKeyPress(object sender, KeyPressEventArgs e)
        {
            // on escape
            if (e.KeyChar == 27)
            {
                HideAutocompleteForm();
                e.Handled = true;
            }
        }

        private void HideAutocompleteForm()
        {
            lastFmAutocompleteForm.BeginInvoke(new MethodInvoker(() => lastFmAutocompleteForm.Hide()));
        }

        private void SilenceUpdateText(string newText)
        {
            silince = true;
            Text = newText;
            this.Select(this.TextLength, 0);
            silince = false;
        }

        private void TextBoxLastfmAutocompleteTextChanged(object sender, EventArgs e)
        {
            if (!silince)
                lastFmAutocompleteForm.OnTextUpdate(this.Text);
        }
    }
}
